﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;
using Serilog.Formatting.Json;
using System;
using NetMicro.Core.ConfigureOptions;
using NetMicro.Core.Helper;
using NetMicro.Trace.Enums;
using NetMicro.Trace.Extensions;
using NetMicro.Trace.Options;
using System.Diagnostics;

namespace NetMicro.Trace
{
    /// <summary>
    /// 日志扩展
    /// </summary>
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 注册日志
        /// </summary>
        /// <param name="services"></param>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static IServiceCollection AddLog(this IServiceCollection services, string serviceName = null)
        {
            services.AddActivityListener();
            services.AddConfigure<LoggingOption>();
            var log = App.GetConfig<LoggingOption>("Logging");

            if (log.WriteToType == WriteToType.None)
            {
                services.AddLogging(m =>
                {
                    m.ClearProviders();
                });
                return services;
            }
            Action<ILoggingBuilder> serilogAction = m =>
            {
                m.ClearProviders();
                m.AddSerilog();
            };

            LoggerConfiguration build = new LoggerConfiguration();
            build.AddSerilogFilter(log);
            build.AddSerilogLelvel(log);
            build.WriteSerilogJson(log);
            build.WriteSerilogText(log);
            build.WriteSerilogConsole(log);
            build.SendEmail(log);
            build.Enrich.WithProperty(Const.Penetrates.ServiceName, serviceName ?? log.ServiceName);
            build.Enrich.AddActivity();
            Log.Logger = build.CreateLogger();
            services.AddLogging(m =>
            {
                serilogAction.Invoke(m);
            });
            return services;
        }

        /// <summary>
        /// 添加活动监听
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>

        private static IServiceCollection AddActivityListener(this IServiceCollection services)
        {
            var activityListener = new ActivityListener
            {
                ShouldListenTo = s => true,
                SampleUsingParentId = (ref ActivityCreationOptions<string> activityOptions) => ActivitySamplingResult.AllData,
                Sample = (ref ActivityCreationOptions<ActivityContext> activityOptions) => ActivitySamplingResult.AllData
            };
            ActivitySource.AddActivityListener(activityListener);
            return services;
        }
    }
}
